package com.nexus.core.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nexus.core.service.dto.BaseDTO;
import com.nexus.core.service.entity.BaseEntity;
import com.nexus.core.service.mapper.IBaseMapper;
import com.nexus.core.service.mapstruct.BaseConverter;
import com.nexus.core.utils.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Service基类
 *
 * @Date 2025/7/24 9:17
 * @Author luzhengning
 **/
public abstract class BaseService<D extends IBaseMapper<T>, T extends BaseEntity, DTO extends BaseDTO, C extends BaseConverter<T, DTO>> extends ServiceImpl<D, T> {

    /**
     * Mapstruct转换
     *
     * @Date 2025/7/24 16:10
     * @Author luzhengning
     **/
    @Autowired
    protected C converter;

    public C getConverter() {
        return this.converter;
    }


    /**
     * 保存
     *
     * @Date 2025/7/24 14:55
     * @Author luzhengning
     **/
    public DTO save(DTO dto) {
        T entity = converter.toEntity(dto);
        boolean save = save(entity);
        dto = converter.toDTO(entity);
        return dto;
    }

    /**
     * 批量保存
     *
     * @Date 2025/7/24 16:04
     * @Author luzhengning
     **/
    public List<DTO> saveBatch(List<DTO> dtoList) {
        List<T> entitys = converter.toEntity(dtoList);
        boolean save = saveBatch(entitys, 10);
        dtoList = converter.toDTO(entitys);
        return dtoList;
    }

    /**
     * 根据ID更新
     *
     * @Date 2025/7/24 14:59
     * @Author luzhengning
     **/
    public DTO update(DTO dto) {
        T entity = converter.toEntity(dto);
        boolean b = updateById(entity);
        dto = converter.toDTO(entity);
        return dto;
    }

    /**
     * 批量更新
     *
     * @Date 2025/7/24 16:05
     * @Author luzhengning
     **/
    public List<DTO> updateBatch(List<DTO> dtoList) {
        List<T> entitys = converter.toEntity(dtoList);
        boolean b = updateBatchById(entitys, 10);
        dtoList = converter.toDTO(entitys);
        return dtoList;
    }

    /**
     * 保存或更新
     *
     * @Date 2025/7/24 15:02
     * @Author luzhengning
     **/
    public DTO saveOrUpdate(DTO dto) {
        if (ObjectUtils.isEmpty(dto.getId())) {
            dto = save(dto);
        } else {
            dto = update(dto);
        }
        return dto;
    }

    /**
     * 批量保存和更新
     *
     * @Date 2025/7/24 16:07
     * @Author luzhengning
     **/
    public List<DTO> saveOrUpdateBatch(List<DTO> dtoList) {
        List<DTO> insertList = dtoList.stream().filter(item -> ObjectUtils.isEmpty(item.getId())).collect(Collectors.toList());
        List<DTO> updateList = dtoList.stream().filter(item -> ObjectUtils.isNotEmpty(item.getId())).collect(Collectors.toList());
        List<DTO> dataList = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(insertList)) {
            dataList.addAll(saveBatch(insertList));
        }
        if (ObjectUtils.isNotEmpty(updateList)) {
            dataList.addAll(updateBatch(updateList));
        }
        return dataList;
    }

    /**
     * 根据ID删除
     *
     * @Date 2025/7/24 14:54
     * @Author luzhengning
     **/
    public boolean removeById(String id) {
        return removeById(id);
    }

    /**
     * 将DTO列表转换为Map，通过指定字段作为key
     *
     * @param dataList     DTO列表
     * @param keyExtractor 提取key的函数（指定要作为key的字段）
     * @return 以指定字段为key、DTO为value的Map
     * @Date 2025/7/24 16:19
     * @Author luzhengning
     **/
    public Map<Object, DTO> toMap(List<DTO> dataList, Function<DTO, Object> keyExtractor) {
        if (ObjectUtils.isEmpty(dataList)) {
            return new HashMap<>();
        }
        // 过滤null值，通过keyExtractor提取key，遇到重复key时保留第一个
        return dataList.stream().filter(dto -> dto != null).filter(dto -> {
            Object key = keyExtractor.apply(dto);
            return ObjectUtils.isNotEmpty(key);
        }).collect(Collectors.toMap(keyExtractor, dto -> dto, (existing, replacement) -> existing));
    }

    /**
     * 通过id转换的方法
     *
     * @Date 2025/7/24 16:21
     * @Author luzhengning
     **/
    public Map<Object, DTO> toMap(List<DTO> dataList) {
        return toMap(dataList, DTO::getId);
    }

    /**
     * 将 DTO 列表转换为 Map_List
     *
     * @param dataList     DTO 列表
     * @param keyExtractor 提取 key 的函数（指定要作为 key 的字段）
     * @return 以指定字段为 key、DTO 列表为 value 的 Map
     * @Date 2025/7/24 16:24
     * @Author luzhengning
     **/
    public Map<Object, List<DTO>> toMapList(List<DTO> dataList, Function<DTO, Object> keyExtractor) {
        if (ObjectUtils.isEmpty(dataList)) {
            return new HashMap<>();
        }
        // 过滤 null 值，通过 keyExtractor 提取 key，相同 key 的元素会被收集到 List 中
        return dataList.stream().filter(dto -> dto != null).filter(dto -> {
            Object key = keyExtractor.apply(dto);
            return ObjectUtils.isNotEmpty(key);
        }).collect(Collectors.groupingBy(keyExtractor, Collectors.toList()));
    }

}
